package nobnak.study.gl;

public class BezierCurveModel {
	public static final int P0 = 0;
	public static final int P1 = 1;
	public static final int P2 = 2;
	public static final int P3 = 3;
	
	private BezierCurveBuilder builder;
	private Point[] points;
	
	// Constructors
	public BezierCurveModel(BezierCurveBuilder builder, float[] points) {
		this.builder = builder;
		this.points = new Point[] { 
			new Point(points[0], points[1]), new Point(points[2], points[3]),
			new Point(points[4], points[5]), new Point(points[6], points[7])
		};
	}
	
	// Methods
	public float[] getPoints() {
		return new float[] {
			points[0].x, points[0].y, points[1].x, points[1].y,
			points[2].x, points[2].y, points[3].x, points[3].y
		};
	}
	public float[] tessellate() {
		return builder.makeBezierCurve(
				points[0].x, points[0].y, 
				points[1].x, points[1].y, 
				points[2].x, points[2].y, 
				points[3].x, points[3].y
						).tessellate();
	}
	public int findNearestPoint(float x, float y) {
		float minimul = Float.MAX_VALUE;
		int result = 0;
		for (int i = 0; i < points.length; i++) {
			Point p = points[i];
			float d = (p.x - x) * (p.x - x) + (p.y - y) * (p.y - y);
			if (d < minimul) {
				minimul = d;
				result = i;
			}
		}
		return result;
	}
	public PointManipulator makePointManipulator(int index) {
		final Point p = points[index];
		return new PointManipulator() {
			@Override
			public void move(float dx, float dy) {
				p.x += dx;
				p.y += dy;
			}
		};
	}

	// Interfaces
	private class Point {
		private float x;
		private float y;
		
		public Point(float x, float y) {
			this.x = x;
			this.y = y;
		}
	}
	public interface PointManipulator {
		void move(float dx, float dy);
	}
}
